<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1">
	<meta http-equiv="pragma" content="no-cache" />
    <meta name="author" content="Jayli" />
	<meta name="keywords" content="淘宝UED 前端工程师 拔赤" />	
	<meta name="description" content="淘宝前端工程师拔赤，关注尖端前端技术，关注yui" />
	<meta http-equiv="imagetoolbar" content="no" />
	<meta name="title" content="拔赤的文章列表" />
    <title>编码那些事</title>
    <link href="http://jayli.github.com/blog/atom.xml" rel="alternate" title="setImpl" type="application/atom+xml" />
    <link rel="stylesheet" href="http://jayli.github.com/blog/media/css/style.css">
    <link rel="stylesheet" href="http://jayli.github.com/blog/media/css/github.css">
	<style>
	</style>
    <script type="text/javascript" src="http://jayli.github.com/blog/media/js/highlight.pack.js"></script>
    <script type="text/javascript">
      hljs.initHighlightingOnLoad();
    </script>
	<!--[if lte IE 8]>
	<script src="http://a.tbcdn.cn/apps/lottery/00023/index-v3/js/html5.js"></script>
	<![endif]-->
	<meta name="baidu-tc-verification" content="afb6c9df553ef3493d9ee65263df0d55" />
	<script src="http://siteapp.baidu.com/static/webappservice/uaredirect.js" type="text/javascript"></script><script type="text/javascript">uaredirect("http://m.zoojs.org", "http://jayli.github.com/blog");</script>
  </head>
  <body>
    <div id="container">
      <div id="main" role="main">
        <header>
        <h1>编码那些事</h1>
        </header>
        <nav>
        <span><a title="home page" class="" href="/blog/index.html">home</a></span>
        <span><a title="tags" class="" href="/blog/tags.html">tags</a></span>
        <span><a title="about" class="" href="/blog/about.html">about me</a></span>
        <span><a title="flickr" class="" href="http://www.flickr.com/photos/lijing00333">flickr</a></span>
        <span><a title="blogroll" class="" href="/blog/links.html">links</a></span>
        <span><a title="projects" class="" href="/blog/projects.html">projects</a></span>
        <span><a title="subscribe me" class="" href="/blog/atom.xml">feed</a></span>
        </nav>
        <article class="content">
        <section class="post">
<p>前端开发中编码的问题一向是让人头疼的，尤其是在以gbk为基础页面编码的淘宝，情况更加复杂，除了常见的页面文件的编码之外，对不同编码js/css文件的引用、meta的charset设置、表单提交的URL编码等问题的处理稍微粗心就会出问题，特别是ajax中的编码转换，始终缺乏统一方便的解决方案，今天我们就分享两个js转码的常见案例的解决。首先，我们应当了解编码相关的一些基本概念：</p>

<ul>
<li>gbk和utf-8是不兼容的两种编码，unicode是万国码码表的简称</li>
<li>utf-8编码是unicode的一种实现</li>
<li>js引擎的内码是unicode</li>
<li>URL编码是将字符裸码以16进制显示出来，每个字之前冠以“%”</li>
<li>因此，URL编码的结果只唯一和字符当前存储的裸码有关，原则上转换过程不查任何码表</li>
<li>unicode码表中，中文字符的范围为4E00到9FA5</li>
<li>js所识别的unicode表示形式为“\uXXYY”</li>
<li>js中的encodeURI是对字符串进行URL编码，编码基于utf-8的裸码</li>
<li>js中的escape是对字符串进行unicode转码，转码基于unicode码表</li>
<li>form表单提交会对参数进行URL编码，编码所基于的裸码类型和页面编码有关</li>
</ul>


<p>基于以上知识点，可以初步得出：</p>

<ul>
<li>js无法直接进行基于gbk裸码的url编码</li>
<li>js无法直接进行转换为’\uXXYY’形式的unicode编码</li>
</ul>


<p>而在ajax过程中，通过js传参经常会遇到需要gbk url编码和直接传输unicode编码的情况，尤其当通过json传数据的时候。在php中，对一个对象进行<code>json_encode</code>转换的时候，会自动将中文转换为unicode，这里的unicode可以直接被js识别，因此在js中是只要将json串转换为对象即可，不用解码，php代码为：</p>

<pre><code>$a = array(‘a’=&gt;11,’b'=&gt;’淘宝’);//json
echo json_encode($a);//输出 {“a”:11,”b”:”\u6dd8\u5b9d”}
</code></pre>

<p>而php中进行url编码默认是以utf8的方式</p>

<pre><code>//输出 %E6%B7%98%E5%AE%9D ，这里是utf8方式的URL编码
echo urlencode(‘淘宝’);
</code></pre>

<p>如果想进行gbk方式的URL编码，则可以</p>

<pre><code>$s = ‘淘宝’;
$g = iconv(‘utf-8′, ‘gbk’,$s);//utf8字符串转换为gbk字符串
echo urlencode($g);//输出 %CC%D4%B1%A6 ，这里是gbk方式的URL编码
</code></pre>

<p>php中对URL编码的解码是上面的逆操作</p>

<pre><code>//gbk URL解码:输出 淘宝
echo urldecode(‘%CC%D4%B1%A6′);
//utf8 URL解码:输出 淘宝
echo iconv(‘utf-8′,’gbk’,urldecode(‘%E6%B7%98%E5%AE%9D’));
</code></pre>

<p>这里，我们用模拟表单提交的方法来实现js中的gbk URL编码，因为，gbk编码的页面的form表单提交的URL编码是和页面编码一致的，我们模拟表单提交给一个隐藏的iframe，然后取得iframe的src中的提交结果，就得到了gbk URL编码</p>

<p>gbk URL编码的demo。</p>

<p>而如果要在js中模拟php中的<code>json_encode</code>只对中文进行unicode编码，则需要遍历字符串，用escape作转换，然后替换没用的字符</p>

<pre><code>//js中只对中文进行unicode编码
var foo = function(s){
    return s.replace(/[\u4E00-\u9FA5]/ig,function(w){
        return escape(w).toLowerCase().replace(/%/ig,’\\’);
    });
};
</code></pre>

<p>若对所有字符进行unicode编码，则直接escape就可以了</p>

</section>
<section class="meta">

<!--span class="tags">
  tagged by 
  
</span-->

<span class="time">
  posted at <time datetime="2010-12-13">2010-12-13</time>
</span>
</section>

<section class="comment">
<div id="disqus_thread"></div>
<script type="text/javascript">
    /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
    var disqus_shortname = 'jayliblog'; // required: replace example with your forum shortname
	var disqus_identifier = 'urn:uuid:a64ac2af-7307-4429-bbe0-85de1bea2a4f';

    /* * * DON'T EDIT BELOW THIS LINE * * */
    (function() {
        var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
        dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
</section>


        </article>
      </div>
    </div> <!--! end of #container -->
  </body>
</html>
